{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Example KubeHound queries \n",
    "\n",
    "This file contains examples queries for kubehound. This file should be mostly read only. No modification will be ported to the original file, it will be kept only for the duration of the docker container.\n",
    "\n",
    "Note: You may need to adjust the value on the cell below and execute (ctrl + enter) before running any other cells."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initial Setup\n",
    "\n",
    "Connection is being initated directly from the docker using the env vars `GRAPH_NOTEBOOK_HOST` and `GRAPH_NOTEBOOK_PORT`. To overwrite it you can use the magic `%%graph_notebook_config` [details here](https://github.com/aws/graph-notebook/tree/main/additional-databases/gremlin-server#connecting-to-a-local-gremlin-server-from-jupyter).\n",
    "\n",
    "Now set the appearance customizations for the notebook. You can see a guide on possible options [here](https://github.com/aws/graph-notebook/blob/623d43827f798c33125219e8f45ad1b6e5b29513/src/graph_notebook/notebooks/01-Neptune-Database/02-Visualization/Grouping-and-Appearance-Customization-Gremlin.ipynb#L680)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "init_cell": true
   },
   "outputs": [],
   "source": [
    "%%capture \"Remove this line to see debug information\"\n",
    "%%graph_notebook_vis_options\n",
    "{\n",
    "  \"edges\": {\n",
    "    \"smooth\": {\n",
    "      \"enabled\": true,\n",
    "      \"type\": \"dynamic\"\n",
    "    },\n",
    "    \"arrows\": {\n",
    "      \"to\": {\n",
    "        \"enabled\": true,\n",
    "        \"type\": \"arrow\"\n",
    "      }\n",
    "    }\n",
    "  }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Critical Path Queries"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### All critical paths from external services\n",
    "\n",
    "Critical paths from external services can highlight most likely paths an attacker can take following the compromise of an external service. In a well-configured cluster, such paths should be limited to very few (if any) services.\n",
    "\n",
    "**NOTE** an `ENDPOINT_EXPLOIT` edge does not signal that the endpoint is *necessarily* exploitable but serves as a useful starting point for path traversal queries\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin -d class -g critical -le 50 -p inv,oute\n",
    "kh.services()\n",
    "    .criticalPaths()\n",
    "    .by(elementMap())\n",
    "    .limit(100)  // Limit the number of results for large clusters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### All critical paths from groups\n",
    "\n",
    "Critical paths from groups can highlight overprivileged groups and help quickly assess the impact of compromised credentials."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin -d class -g critical -le 50 -p inv,oute\n",
    "kh.groups()\n",
    "    .criticalPaths()\n",
    "    .by(elementMap())\n",
    "    .limit(100)  // Limit the number of results for large clusters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Complex critical path queries\n",
    "The [KubeHound DSL](https://kubehound.io/queries/dsl/) is fully compatible with the Gremlin language, so you can use any gremlin function in your queries to add additional filters if needed. The example below attempts to filter for Kubernetes services exposed on port 443 attached to `elasticsearch` containers, and limits attack paths to 6 hops or less."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%gremlin -d class -g critical -le 50 -p inv,oute\n",
    "kh.services()\n",
    "    .has(\"port\", 443)   // Look for exposed port on 443 only\n",
    "    .not(\n",
    "        // Exclude endpoints from the 'kube' and 'system' namespaces\n",
    "        has(\"namespace\", within(\"system\", \"kube\")) \n",
    "    )    \n",
    "    .where(\n",
    "         // Only accept endpoints attached to elasticsearch containers\n",
    "        __.out().hasLabel(\"Container\").has(\"image\", TextP.containing(\"elasticsearch\"))\n",
    "    ) \n",
    "    .criticalPaths(6)   // Limit to critical paths of 6 hops or less\n",
    "    .by(elementMap())\n",
    "    .limit(100)  // Limit the number of results for large clusters"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "See the [documentation](https://kubehound.io/queries/dsl/#criticalpaths-step) for further examples of critical path analysis"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
